package com.gao.l_volatile.a;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

// 本例用来测试volatile所修饰的变量对于线程的可见性
// 注意，在不使用volatile的情況下，在while循环中打印b，也能强制线程去主内存中刷新b的值。

public class App2 {
	 /*volatile*/ boolean b = true;

	Map map = new HashMap<>();

	static String s = "";

	volatile int x = 0;

	void f1() {
		System.out.println("start");

		while(b){

//			try {
//			    Thread.sleep(1);		// 当执行该线程的cpu有空闲时，他会去主存读取一下共享变量的值来更新线程工作内存中的值
//			} catch(Exception e) {
//			    e.printStackTrace();
//			}

//			File f = new File("D:\\");  // 如果加上这一行，会产生IO操作，线程就会会从主存中读取b的值

//			synchronized ("abc") {	// 如果加上这一段，线程会从主存中读取b的值
//				int x = 5;
//				x += 6;
//			}

//			x = 1;					// 在b没有被volatile修饰的情况下，我们写了另外一个被volatile修饰的变量，也会让当前线程从主内存读取b

//			 map.clear(); map.put("b", b);	// 如果加上这一行，线程也会从主存中读取b，这找不到什么道理，这个行为是不可预知的。总之，在当前环境下，把变量存入map中，线程就会从主存中读取变量的值！
		}
//		b = false;	// 加入这一行，就能够在汇编中，看到lock汇编前缀
		System.out.println("end");
	}

	public static void main(String[] args) throws IOException {
		App2 app = new App2();
		new Thread(new Runnable() {
			@Override
			public void run() {
				app.f1();
			}
		}).start();

		System.out.println("Enter...");
		System.in.read();

		app.b = false;
		System.out.println("set b to false..");
	}
}